iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0

昨天我們簡單看了基礎型別(三個原始值、陣列、function),跟一些使用方法,今天繼續看TypeScript讓你開發更便捷的地方!

TypeScript會提示你可取用的方法/屬性

除了昨天提到的,你可以設定參數跟回傳值的型別外,當你已經設定好參數的型別,並且要在函式內使用該參數的方法或屬性時,編輯器會在你打錯字、取用錯誤的屬性時提醒你!

let people: string[] = ["John", "Ted", "Allen"]
people.forEach(name=>{
	console.log(name.touppercase())
//Property 'touppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?
})

function sayHi(person:{name: string, age: number}){
	console.log(person.address)
//Property 'address' does not exist on type '{ name: string; age: number; }'.
}

第一個例子中,因為TypeScript知道我們的people都是字串,所以對這陣列使用forEach後,他也會知道裡面的name是什麼型別,就會幫我們去判斷,我們在name後綴的屬性/方法,是否真實存在,像這邊,我們拼錯了toUpperCase(),這個錯誤在我們一打完字就被發現了,不會等到執行時才在console看到name.touppercase is not a function,非常方便。

拼錯字的說明

直接問你要不要更正
旁邊的燈泡甚至會直接問你:要不要幫你改成toUpperCase?

第二個例子sayHi當中,由於我們設定的參數person物件,並沒有一個屬性叫做address,所以TypeScript也很明確的噴出錯誤。跟昨天的processInput例子類似,當我們輸入到person.之後,TypeScript會提示你:「person只有agename這兩個屬性, 且age的型別是數字」,這樣一來,要是person的屬性有很多、或者說屬性名稱沒這麼好記,你就不用特地回去翻找你的屬性的確切拼法是什麼了,可以省下一些時間。

你打錯屬性囉

Type Union型別聯集

先前的例子裡,我們都只為變數或參數設定了"單一種"型別,但我們也有可能想讓某個值同時接納兩種(或以上)的型別。

function sayHi2(person: string | number){
	console.log(person)
}
sayHi2("John")
sayHi2(9527)  //知道這個的應該有點年紀了...
//上述這兩行都不會有錯

sayHi2({name:"Ronald"})
//Argument of type '{ name: any; Ronald: any; }' is not assignable to parameter of type 'string | number'.
//應該滿明顯的,我們就只接受字串跟數字當作參數的型別

這樣做好像很方便,我們可以不侷限於一種型別。但,上述例子中使用了型別聯集,不代表你可以對person同時使用"所有"string跟number的方法。

function sayHi2(person: string | number){
	console.log(person.toUpperCase())
}
//Property 'toUpperCase' does not exist on type 'string | number'.  Property 'toUpperCase' does not exist on type 'number'.
//如果這邊我們用的是person.toString()就不會報錯,因為不管是字串或數字,都有.toString方法

意思就是,你必須使用”同時存在於字串與數字的方法”,所以名義上叫聯集,從功能上來看反而算是”交集”。
所以,要處理這個錯誤,你就必須在函式內對person型別進行一層型別防衛(Type guard):

function sayHi2(person: string | number){
  if(typeof person ==="string"){
	console.log(person.toUpperCase())
//這樣就不會噴錯了
  }
}

型別別名(Type alias)

再來講今天最後一個觀念:型別別名(Type alias)

今天一直在範例中看到(person: string | number),但要是這個型別判斷需要一直在專案中出現,一直重複打字或複製貼上,對於工程師來講都是很不明智的一件事。所以,我們可以特定為這組型別命名,方便我們後續使用。

type Person = string | number

function sayHi3(person: Person){
  if(typeof person ==="string"){
	console.log(person.toUpperCase())
  }
}

function sayHi4(person: Person){
 //進行不同操作
}

如此就能省去不少時間,而且在語意上因為有了別名,我們對於這個參數又有更多的瞭解了!(雖然這裡我取名叫Person,但要是專案內有Customer、Staff、Supervisor等身份作為型別別名,就會更有意義了lol)
type Person

今天先講這些,明天再繼續聊TypeScript的基礎型別及功能!
明天會提到使用型別聯集時,也會搭配使用的東西:型別斷言(Type assertion)


上一篇
簡單型別介紹!
下一篇
型別介紹part3 - 型別斷言
系列文
你也對開始使用typescript感到無力嗎?我也是 - 30天初探typescript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言